# 作者：贺智翔

from requests.structures import CaseInsensitiveDict
import requests
import json
import csv
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

print("""
************************************Redfish批量设置功率封顶 作者：贺智翔；张泽************************************
***********************************************使用说明***************************************************
1.将需要批量配置的BMC信息填入BMClist.csv，由于未设置标题行，从第一行开始逐行填写。
填写格式：
    IP1,UserName,Password,Watts,Actions
    IP2,UserName,Password,Watts,Actions
    IP3,UserName,Password,Watts,Actions
其中：Watts范围：150W-1000W，刀片不支持。
    Actions表示超出封顶功率时动作：NoAction：无操作；HardPowerOff：关机
示例：
    1.1.1.1,admin,password,777,NoAction 
    1.1.1.2,admin,password,777,NoAction
2.运行xx.exe脚本批量部署。
3.脚本运行完成后会在当前路径生成log，可以查看脚本运行情况。
4.如果BMClist.csv中信息不准确会导致程序中断，需要重新检查并修改BMClist.csv中对应错误行的信息并重新运行程序。
5.xx.py是python源码，可按需进行调试更改但需要自行下载pyinstaller.exe重新编译成exe。

***********************************************免责声明***************************************************
1.本脚本仅为测试用途，请使用方在业务环境中使用和编译该脚本时自行评估风险并承担使用该脚本引起的一切问题。
2.开发者不对本脚本做后续维护和开发（包括但不限于：脚本功能定制、脚本故障排查等）。
*********************************************************************************************************
""")
Agree1 = input("是否已阅读使用说明，并按照说明填写BMClist？Y/N： ")
Agree2 = input("是否已阅读《免责声明》并同意该声明？Y/N： ")
if (Agree1  and  Agree2) == "Y" or (Agree1  and  Agree2) =="y":
    print("Loading....")
    with open("log.csv", "w", encoding="utf-8", newline='') as csvfile:
        fieldnames = ['BMCIP' , 'Result']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        csvfile.close()
        print("创建日志文件--->log.csv")
    with open('BMClist.csv') as f:
        reader = csv.reader(f)
        print("打开BMClist获取服务器登录信息")
        for row in reader:
            IP = (str(row[0]))
            USR = (str(row[1]))
            PWD = (str(row[2]))
            Watts=(str(row[3]))
            Actions = (str(row[4]))
            try:
                print("---------------------正在为HDM IP地址为%s的服务器设置功率封顶---------------------------" % IP)
                print(Watts + " " + Actions)
                url = 'https://%s/redfish/v1/Chassis/1/Power' % IP
                headers = CaseInsensitiveDict()
                getrequest = requests.get(url, auth=('%s' % USR, '%s' % PWD), verify=False)  # 发送一次Get报文，并将回显报文拿到；
                print(getrequest)
                etag = getrequest.headers["ETag"]  # 抓取回显报文中的Etag标签命名为etag
                print(etag)
                headers["if-Match"] = etag  # 将etag赋给"if-Match"
                headers["Content-Type"] = "application/json"
                data1 = ('{\"PowerControl\": [{\"PowerLimit\": {\"LimitInWatts\": %s, \"LimitException\": "%s"}}]}' % (Watts, Actions))
                patchrequest = requests.patch(url, headers=headers, data=data1, auth=('%s' % USR, '%s' % PWD), verify=False)
                if patchrequest.status_code == 200:
                    print("功率封顶设置成功!")
                    Result = str(True)
                else:
                    print("功率封顶设置失败!")
                    Result = str(False)
            except:
                print('程序执行异常，请检查中断位置csv源数据是否正确！')
                Result = str(False)
            with open("log.csv", "a+", encoding="utf-8", newline='') as csvfile:
                fieldnames = ['BMCIP', 'Result']
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                writer.writerow({'BMCIP': str(IP), 'Result': Result})
                print("程序执行结果写入日志--->log.csv!")
            continue
else:
    print("您未阅读并同意使用说明，程序无法执行。")

Over = input("""

*************************************程序执行结束,请按回车键退出！****************************************

""")